#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <vector>

// 1. 报文和报文之间，我们采用特殊字符来进行解决粘报问题
// 2. 获取一个一个独立完整的报文，序列和反序列化 -- 自定义
// 100+19X100+19X100+19

// 支持解决粘报问题，处理独立报文
#define SEP "X"
#define SEP_LEN strlen(SEP)

// 我们要把传入进来的缓冲区进行切分
// 1. buffer被切走的，也同时要从buffer中移除
// 2. 可能会存在多个报文，多个报文依次放入out
// buffer: 输入输出型参数
// out: 输出型参数

void SplitMessage(std::string &buffer, std::vector<std::string> *out)
{
    while (true)
    {
        auto pos = buffer.find(SEP);
        if (std::string::npos == pos)
            break;
        std::string message = buffer.substr(0, pos);
        buffer.erase(0, pos + SEP_LEN);
        out->push_back(message);
    }
}

#define SPA " "
#define SPACE_LEN strlen(SPA)

std::string Encode(std::string &s)
{
    return s + SEP;
}

class Request
{
public:
    // 1.自主实现
    // 2.使用现成的方案
    // _x _rule _y
    std::string serialization()
    {

        std::string str;
        str = std::to_string(_x);
        str += SPA;
        str += _rule;
        str += SPA;
        str += std::to_string(_y);
        return str;
    }
    // _x _rule _y
    bool Deserialization(const std::string &str)
    {

        ssize_t left = str.find(SPA);
        if (left == std::string::npos)
            return false;
        ssize_t right = str.rfind(SPA);
        if (right == std::string::npos)
            return false;
        _x = atoi(str.substr(0, left).c_str());
        _y = atoi(str.substr(right + SPACE_LEN).c_str());
        _rule = str[left + SPACE_LEN];
    }

public:
    Request() {}
    Request(int x, int y, int rule) : _x(x), _y(y), _rule(rule)
    {
    }
    ~Request() {}

public:
    int _x;
    int _y;
    char _rule;
};
class Response
{
public:
    // _code _result
    std::string serialization()
    {

        std::string str;
        str = std::to_string(_code);
        str += SPA;
        str += std::to_string(_result);
        return str;
    }
    // _code _result
    bool Deserialization(const std::string &str)
    {

        ssize_t pos = str.find(SPA);
        if (pos == std::string::npos)
            return false;
        _code = atoi(str.substr(0, pos).c_str());
        _result = atoi(str.substr(pos + SPACE_LEN).c_str());
        return true;
    }

public:
    Response() {}
    Response(int result, int code)
        : _result(result), _code(code)
    {
    }
    ~Response() {}

public:
    int _result;
    int _code; // 错误码
};
